home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #
- # Copyright 2008 Canonical Ltd
- # Includes code from GDebi, Copyright 2007 Martin B├╢hm <martin.bohm@ubuntu.com>
- #
- # AUTHOR:
- # Jonathan Riddell <jriddell@ubuntu.com>
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License as published
- # by the Free Software Foundation; either version 2 of the License, or (at
- # your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- import sys
-
- from PyKDE4.kdecore import ki18n, KAboutData, KCmdLineArgs
- from PyKDE4.kdeui import KApplication, KMainWindow
-
- from PyQt4.QtGui import *
- from PyQt4.QtCore import *
- from PyQt4 import uic
-
- import apt_pkg
- from GDebi.DebPackage import DebPackage, Cache
- from GDebi.KDEAptDialogs import *
-
- class DumbTerminal(QTextEdit):
- """ a very dumb terminal """
- def __init__(self, parent_frame):
- """ really dumb terminal with simple editing support """
- QTextEdit.__init__(self, parent_frame)
- self.setFontFamily("Monospace")
- self.setFontPointSize(8)
- self.setWordWrapMode(QTextOption.NoWrap)
- self.setUndoRedoEnabled(False)
- self._block = False
- self.connect(self, SIGNAL("cursorPositionChanged(int,int)"), self.onCursorPositionChanged)
-
- def setInstallProgress(self, installProgress):
- self.installProgress = installProgress
-
- def insertWithTermCodes(self, text):
- """ support basic terminal codes """
- display_text = ""
- for c in text:
- # \b - backspace
- if c == chr(8):
- self.moveCursor(QTextEdit.MoveBackward, QTextCursor.KeepAnchor)
- self.cut() #self.removeSelectedText() FIXME
- # \r - is filtered out
- elif c == chr(13):
- pass
- # \a - bell - ignore for now
- elif c == chr(7):
- pass
- else:
- display_text += c
- self.insertPlainText(display_text)
-
- def keyPressEvent(self, ev):
- """ send (ascii) key events to the pty """
- # no master_fd yet
- if not hasattr(self.installProgress, "master_fd"):
- return
- # special handling for backspace
- if ev.key() == Qt.Key_Backspace:
- #print "sent backspace"
- os.write(self.installProgress.master_fd, chr(8))
- return
- # do nothing for events like "shift"
- if not ev.text():
- return
- # now sent the key event to the termianl as utf-8
- os.write(self.installProgress.master_fd, ev.text().toUtf8())
-
- def onCursorPositionChanged(self, x, y):
- """ helper that ensures that the cursor is always at the end """
- if self._block:
- return
- # block signals so that we do not run into a recursion
- self._block = True
- para = self.paragraphs() - 1
- pos = self.paragraphLength(para)
- self.moveCursor(QTextCursor.End)
- self._block = False
-
- class MainWindow (QDialog):
- def __init__ (self, mode, packages):
- QDialog.__init__ (self)
-
- if os.path.exists("install-package.ui"):
- APPDIR = QDir.currentPath()
- else:
- file = KStandardDirs.locate("appdata", "install-package.ui")
- APPDIR = file.left(file.lastIndexOf("/"))
- uic.loadUi(APPDIR + "/install-package.ui", self)
- self.setWindowTitle(i18n("Package Install"))
- self.setWindowIcon(KIcon("applications-other"))
-
- self.cprogress = CacheProgressAdapter(self.installationProgress)
- self._cache = Cache(self.cprogress)
-
- self.mode = mode
- action = False
- self.packages = []
- for package in packages:
- if not package in self._cache:
- print "no such package " + package
- elif mode == "install":
- if not self._cache[package].isInstalled:
- action = True
- self.packages.append(package)
- self.titleLabel.setText(i18nc("package name", "<b>Installing %1</b>", package))
- self._cache[package].markInstall()
- elif mode == "uninstall":
- if self._cache[package].isInstalled:
- action = True
- self.packages.append(package)
- self.titleLabel.setText(i18nc("package name", "<b>Uninstalling %1</b>", package))
- self._cache[package].markDelete()
-
- if action or mode =="update":
- if mode == "install":
- #need to check for plural, else it complains about too many args because the plural string doesn't use %2
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>Installing %2</b>", "<b>Installing packages</b>", len(self.packages), self.packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Installing packages</b>"))
- elif mode == "uninstall":
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>Uninstalling %2</b>", "<b>Uninstalling packages</b>", len(self.packages), self.packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Uninstalling packages</b>"))
- self.buttonBox.hide()
- self.readyInstall()
- else:
- if mode == "install":
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>%2 is already installed</b>", "<b>Requested packages are already installed</b>", len(packages), packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Requested packages are already installed</b>"))
- elif mode == "uninstall":
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>%2 is already uninstalled</b>", "<b>Requested packages are already uninstalled</b>", len(packages), packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Requested packages are already uninstalled</b>"))
- self.installFrame.hide()
- self.connect(self.buttonBox, SIGNAL("clicked(QAbstractButton*)"), self.quit)
- QTimer.singleShot(10, self.resizing)
-
- def quit(self):
- self.hide()
- sys.exit() #QApplication.exit() causes a crash :(
-
- def readyInstall(self):
- self.konsoleFrameLayout = QHBoxLayout(self.konsoleFrame)
- self.newKonsole()
- self.fprogress = KDEFetchProgressAdapter(self.installationProgress, self.installingLabel, self)
- self.iprogress = KDEInstallProgressAdapter(self.installationProgress, self.installingLabel, self)
- self.konsole.setInstallProgress(self.iprogress)
- self.showDetailsButton.setText(i18n("Show Details >>>"))
- if self.mode == "update":
- self.showDetailsButton.hide()
- self.konsoleFrame.hide()
- self.connect(self.showDetailsButton, SIGNAL("clicked()"), self.showDetails)
- self.installationProgress.setValue(0)
- QTimer.singleShot(1000, self.commit)
-
- def newKonsole(self):
- self.konsole = DumbTerminal(self.konsoleFrame)
- self.konsoleFrame.setMinimumSize(500, 400)
- self.konsoleFrameLayout.addWidget(self.konsole)
-
- def showDetails(self):
- if self.konsoleFrame.isVisible():
- self.konsoleFrame.hide()
- self.showDetailsButton.setText(i18n("Show Details >>>"))
- QTimer.singleShot(10, self.resizing)
- else:
- self.konsoleFrame.show()
- self.showDetailsButton.setText(i18n("<<< Hide Details"))
-
- def resizing(self):
- self.resize(self.minimumSizeHint())
-
- def commit(self):
- apt_pkg.PkgSystemLock()
- if self.mode == "update":
- result = self._cache.update(self.fprogress)
- else:
- result = self._cache.commit(self.fprogress,self.iprogress)
- if result:
- if self.mode == "install":
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>%2 successfully installed</b>", "<b>Successfully installed</b>", len(self.packages), self.packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Successfully installed</b>"))
- elif self.mode == "uninstall":
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>%2 successfully uninstalled</b>", "<b>Successfully installed</b>", len(self.packages), self.packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Successfully installed</b>"))
- elif self.mode == "update":
- self.titleLabel.setText(i18n("<b>Successfully updated</b>"))
- self.installFrame.hide()
- else:
- if self.mode == "install":
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>Failed to install package '%2'</b>", "<b>Failed to install packages</b>", len(self.packages), self.packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Failed to install packages</b>"))
- elif self.mode == "uninstall":
- if len(self.packages) == 1:
- self.titleLabel.setText(i18ncp("package name", "<b>Failed to uninstall package '%2'</b>", "<b>Failed to uninstall packages</b>", len(self.packages), self.packages[0]))
- else:
- self.titleLabel.setText(i18n("<b>Failed to uninstall packages</b>"))
- elif self.mode == "update":
- self.titleLabel.setText(i18n("<b>Failed to update</b>"))
- self.buttonBox.show()
- QTimer.singleShot(10, self.resizing)
-
- if __name__ == '__main__':
-
- appName = "install-package"
- catalog = ""
- programName = ki18n ("Install Package")
- version = "1.0"
- description = ki18n ("Installs a package")
- license = KAboutData.License_GPL
- copyright = ki18n ("(c) 2008 Canonical Ltd")
- text = ki18n ("")
- homePage = "http://launchpad.net/install-package"
- bugEmail = ""
-
- aboutData = KAboutData(appName, catalog, programName, version, description, license, copyright, text, homePage, bugEmail)
-
- options = KCmdLineOptions()
- options.add("install", ki18n("Install a package"))
- options.add("uninstall", ki18n("Uninstall a package"))
- options.add("update", ki18n("Reload package list"))
- options.add("!+packages", ki18n("Packages to install/uninstall"))
-
- KCmdLineArgs.init(sys.argv, aboutData)
- KCmdLineArgs.addCmdLineOptions(options)
-
- app = KApplication()
- args = KCmdLineArgs.parsedArgs()
-
- packages = []
- if args.isSet("install") and args.count() > 0:
- mode = "install"
- elif args.isSet("uninstall") and args.count() > 0:
- mode = "uninstall"
- elif args.isSet("update"):
- mode = "update"
- else:
- print "Usage: install-package --install <package>, or, --uninstall <package>"
- KMessageBox.sorry(None, i18n("Usage: install-package --install <package>, or, --uninstall <package>"), i18n("Command Use"), KMessageBox.Notify)
- sys.exit(1)
-
- for item in range(args.count()):
- packages.append(unicode(args.arg(item)))
-
- if os.geteuid() != 0:
- text = i18n("Please run this software with administrative rights. To do so, run this program with kdesudo.")
- title = i18n("Need administrative powers")
- KMessageBox.sorry(None, text, title, KMessageBox.Notify)
- sys.exit(1)
-
- mainWindow = MainWindow(mode, packages)
- mainWindow.show()
-
- app.exec_()
-